﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S3.Common;
using S3.DataModel;

namespace S3.Biz
{
    public class InvoicesManager : CommonManager
    {
        /// <summary>
        /// Tong tien khach hang phai tra
        /// </summary>
        /// <param name="invoiceNo">Ma hoa don</param>
        /// <param name="paid">So tien KH da tra</param>
        /// <param name="memberDiscountAmount">giam gia the thanh vien</param>
        /// <param name="billDiscountAmount">giam gia tren tong hoa don</param>
        /// <param name="voucherAmount">phieu giam gia</param>
        /// <param name="extraMoney">phi ngoai le dieu chinh</param>
        /// <returns></returns>
        public decimal CalTotalMoney(string invoiceNo, decimal paid, decimal memberDiscountAmount, decimal billDiscountAmount, decimal voucherAmount, decimal extraMoney, decimal taxPercent)
        {
            decimal result = 0;
            decimal salesRevenue = CalSalesRevenue(invoiceNo, paid, memberDiscountAmount, billDiscountAmount, voucherAmount);
            decimal taxAmount = CalTaxAmount(salesRevenue, taxPercent);
            decimal totalMoney = salesRevenue + taxAmount + extraMoney;


            result = Utils.RoundMoneyTo500Vnd(totalMoney);

            return result;
        }

        /// <summary>
        /// Tinh toan tong tien thu duoc tu viec ban hang. Chua bao gom thue va extra money.
        /// </summary>
        /// <param name="invoiceNo"></param>
        /// <returns></returns>
        public decimal CalSalesRevenue(Invoice invoice)
        {
            decimal result = 0;

            decimal income = invoice.GoodsAmount.Value + invoice.TimingServiceAmount.Value;
            decimal expense = invoice.Paid.Value + invoice.MemberDiscountAmount.Value + invoice.BillDiscountAmount.Value + invoice.VoucherAmount.Value;

            result = income - expense;

            return result;
        }

        public decimal CalSalesRevenue(string invoiceNo, decimal paid, decimal memberDiscountAmount, decimal billDiscountAmount, decimal voucherAmount)
        {
            decimal result = 0;

            // Tien hang hoa
            DailyItemEntryManager dailyItemEntryManager = new DailyItemEntryManager();
            decimal goodsAmount = dailyItemEntryManager.CalTotalTimingServiceMoneyByInvoice(invoiceNo);

            //Tien gio
            DailyTimingEntryManager dailyTimingEntryManager = new Biz.DailyTimingEntryManager();
            decimal timingServiceAmount = dailyTimingEntryManager.CalTotalMoneyByDesk(invoiceNo);

            decimal income = goodsAmount + timingServiceAmount;
            decimal expense = paid + memberDiscountAmount + billDiscountAmount + voucherAmount;

            result = income - expense;

            return result;
        }


        /// <summary>
        /// Tinh toan Tien thue phai tra tren tong Don hang
        /// </summary>
        /// <param name="salesRevenue"></param>
        /// <param name="taxPercent"></param>
        /// <returns></returns>
        public decimal CalTaxAmount(decimal salesRevenue, decimal taxPercent)
        {
            decimal result = 0;

            result = salesRevenue - ((salesRevenue * taxPercent) / 100);

            return result;
        }

        /// <summary>
        /// Tinh toan loi nhuan sau thue.
        /// </summary>
        /// <param name="salesRevenue">Tong tien ban hang</param>
        /// <param name="taxAmount">Tong tien thue</param>
        /// <param name="extraMoney">Chi phi ngoai le dieu chinh</param>
        /// <returns></returns>
        public decimal CalNetIncome(decimal salesRevenue, decimal taxAmount, decimal extraMoney)
        {
            decimal result = 0;

            result = salesRevenue + extraMoney - taxAmount;

            return result;
        }


        #region Delete

        /// <summary>
        /// Xoa 1 ban ghi
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public int Delete(string key)
        {
            try
            {
                //Check deplicate
                var user = _entities.Invoices.FirstOrDefault(a => a.InvoiceNo.ToLower() == key.ToLower());

                //If found
                if (user != null)
                {
                    _entities.DeleteObject(user);
                }

                return _entities.SaveChanges();
            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("InvoicesManager::Delete::", ex, true);
                }
            }

            return 0;
        }

        /// <summary>
        /// Xoa tat ca ban ghi
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>        
        public int DeleteAll()
        {
            try
            {
                var list = _entities.Invoices.ToList();

                if (list != null)
                {
                    list.ForEach(_entities.DeleteObject);

                    return _entities.SaveChanges();
                }

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("Invoices::DeleteAll::", ex, true);
                }
            }

            return 0;
        }
        #endregion

        /// <summary>
        /// Load tat ca danh sach
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>
        #region GetAll
        public IQueryable<Invoice> GetAll()
        {
            try
            {
                return _entities.Invoices.OrderByDescending(i => i.ModifiedDate);

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("Invoices::GetAll::", ex, true);
                }
            }

            return null;
        }
        #endregion

        #region Save
        /// <summary>
        /// Save entry to SQL
        /// </summary>
        /// <param name="item"></param>
        public int Save(Invoice item)
        {
            try
            {
                Invoice entry = null;
                //Check exist first
                // If existing then update else add new
                if (IsExist(ref entry))
                {
                    entry.StaffID = item.StaffID;
                    entry.InvoiceDate = item.InvoiceDate;
                    entry.TimingServiceAmount = item.TimingServiceAmount;
                    entry.GoodsAmount = item.GoodsAmount;
                    entry.NetIncome = item.NetIncome;
                    entry.SalesRevenue = item.SalesRevenue;
                    entry.CustomerID = item.CustomerID;
                    entry.MemberCardID = item.MemberCardID;
                    entry.MemberDiscountPercent = item.MemberDiscountPercent;
                    entry.MemberDiscountAmount = item.MemberDiscountAmount;
                    entry.TimingServiceName = item.TimingServiceName;
                    entry.CountersNo = item.CountersNo;
                    entry.Paid = item.Paid;
                    entry.ExtraMoney = item.ExtraMoney;
                    entry.CashAmount = item.CashAmount;
                    entry.CreditCardAmount = item.CreditCardAmount;
                    entry.PaymentMethod = item.PaymentMethod;
                    entry.CreditCardPaymentInfo = item.CreditCardPaymentInfo;
                    entry.VoucherCode = item.VoucherCode;
                    entry.VoucherAmount = item.VoucherAmount;
                    entry.Note = item.Note;
                    entry.DeliveryStatus = item.DeliveryStatus;
                    entry.PaidStatus = item.PaidStatus;
                    entry.ModifiedBy = item.ModifiedBy;
                    entry.ModifiedDate = item.ModifiedDate;
                    entry.BillDiscountPercent = item.BillDiscountPercent;
                    entry.BillDiscountAmount = item.BillDiscountAmount;
                    entry.TaxAmount = item.TaxAmount;
                    entry.TaxPercent = item.TaxPercent;

                }
                else
                {
                    //Add new                    
                    _entities.AddToInvoices(item);

                }

                //Submit change
                return _entities.SaveChanges();

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("InvoicesManager::Save::", ex, true);
                }
            }

            return 0;

        }
        #endregion

        /// <summary>
        /// Check existing or not
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public bool IsExist(ref Invoice input)
        {
            //Check parameter
            if (input == null) return false;

            var key = input.InvoiceNo;

            try
            {
                var output = _entities.Invoices.Where(a => a.InvoiceNo.ToLower() == key.ToLower());
                return output != null && output.Count() > 0 ? true : false;
            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("InvoiceManager::IsExist::", ex, true);
                }
            }

            return false;
        }
    }
}